package com.infore.siteManagement.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.infore.siteManagement.constant.Constants;
import com.infore.siteManagement.constant.ResultConstants;
import com.infore.siteManagement.dto.ProjectInfoDto;
import com.infore.siteManagement.entity.Project;
import com.infore.siteManagement.entity.ProjectType;
import com.infore.siteManagement.enums.IndexValidate;
import com.infore.siteManagement.enums.ResultStatus;
import com.infore.siteManagement.repository.IIndexTypeRespository;
import com.infore.siteManagement.repository.IProjectAndEquipmentRepository;
import com.infore.siteManagement.repository.IProjectAndStationRepository;
import com.infore.siteManagement.repository.IndexRespository;
import com.infore.siteManagement.select.QueryDispatcher;
import com.infore.siteManagement.select.dto.QueryParamDto;
import com.infore.siteManagement.select.util.QueryUtil;
import com.infore.siteManagement.service.IFilterService;
import com.infore.siteManagement.service.IndexService;
import com.infore.siteManagement.util.ArrayUtils;
import com.infore.siteManagement.util.MyBeanUtils;
import com.infore.siteManagement.util.PageUtil;
import com.infore.siteManagement.util.ProjectTreeUtil;
import com.infore.siteManagement.util.ResultEntity;
import com.infore.siteManagement.vo.ProjectTreeVo;

/**
 * 指标/因子管理服务实现层
 * @author llf
 *
 *
 */

@Service
public class IndexServiceImpl implements IndexService{

	@Autowired
	private IndexRespository iIndexRespository;
	@Autowired
	private QueryDispatcher queryDispatcher;
	@Autowired
	private IIndexTypeRespository indexTypeRespository;
	@Autowired
	private IProjectAndEquipmentRepository iProjectAndEquipmentRepository;
	@Autowired
	private IProjectAndStationRepository iProjectAndStationRepository;
	@Autowired
	private IFilterService iFilterService;
	@Autowired
	private IIndexTypeRespository iIndexTypeRespository;
	
	public ResultEntity queryProject(QueryParamDto queryParamDto) {
		//无任何条件查询
		if (queryParamDto == null) {
			List<Project> list = iIndexRespository.findAll();
			return new ResultEntity(ResultStatus.SUCCESS,ResultConstants.INDEX_QUERY_SUCCESS).setDataList(list);
		//只分页
		}else if (queryParamDto.getPageObject() != null && queryParamDto.getQueryCondition() == null &&
				queryParamDto.getAssembleCondition() == null && queryParamDto.getAssembleSql() ==null) {
			Page<Project> projectPage = iIndexRespository.findAll(queryParamDto.getPageObject().getPageRequest());
			com.infore.siteManagement.util.Page<Project> page = PageUtil.pageConvert(projectPage);
			return new ResultEntity(ResultStatus.SUCCESS,ResultConstants.INDEX_QUERY_SUCCESS).setPage(page);
		//不指定字段
		}else if (StringUtils.isBlank(queryParamDto.getAssembleSql().getSelect())) {
			return queryAll(queryParamDto);
		}
		return queryDispatcher.dispatcher(queryParamDto, Project.class);
	}
	
	@SuppressWarnings("serial")
	public ResultEntity queryAll(QueryParamDto queryParamDto) {
		//判断是否分页
		if (queryParamDto.getPageObject() != null) {
			Page<Project> projectPage = iIndexRespository.findAll(new Specification<Project>() {

				@Override
				public Predicate toPredicate(Root<Project> root, CriteriaQuery<?> query,
						CriteriaBuilder criteriaBuilder) {
					//构建条件
					List<Predicate> predicates = com.infore.siteManagement.select.util.QueryUtil.
							createQueryCondition(queryParamDto, criteriaBuilder, root);
					//组装条件
					Predicate predicate = com.infore.siteManagement.select.util.QueryUtil.
							assembleCondition(queryParamDto, criteriaBuilder, predicates);
					QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
					return query.getRestriction();
				}
			}, queryParamDto.getPageObject().getPageRequest());
			com.infore.siteManagement.util.Page<Project> page = PageUtil.pageConvert(projectPage);
			return new ResultEntity(ResultStatus.SUCCESS,ResultConstants.INDEX_QUERY_SUCCESS).setPage(page);
		} else {
			//不分页查询
			List<Project> list = iIndexRespository.findAll(new Specification<Project>() {

				@Override
				public Predicate toPredicate(Root<Project> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
					//构建条件
					List<Predicate> predicates = com.infore.siteManagement.select.util.QueryUtil.
							createQueryCondition(queryParamDto, criteriaBuilder, root);
					//组装条件
					Predicate predicate =QueryUtil.
							assembleCondition(queryParamDto, criteriaBuilder, predicates);
					QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
					return query.getRestriction();
				}
			});
			return new ResultEntity(ResultStatus.SUCCESS,ResultConstants.INDEX_QUERY_SUCCESS).setDataList(list);
		}
	}

	@Override
	public ResultEntity deleteProject(String ids) {
		try {
			List<String> proList = ArrayUtils.stringToList(ids);
			List<Project> projects = iIndexRespository.findByProjectIdIn(proList);
			if (projects != null && projects.size() > 0 && proList.size() > 0) {
				List<String> codes = projects.stream().filter(l -> l.getProjectCode() != null)
						.map(m ->m.getProjectCode()).collect(Collectors.toList());//因子code
				//删除相关联的
				iProjectAndEquipmentRepository.deleteByprojectIdIn(proList);//删除仪器因子表
				iProjectAndStationRepository.deleteByProjectCodeIn(codes);//删除因子站点表
				iIndexRespository.deleteByProjectIdIn(proList);//删除因子表
			}
		} catch (Exception e) {
			return new ResultEntity(ResultStatus.ERROR,ResultConstants.INDEX_DELETE_ERROR);
		}
		return new ResultEntity(ResultStatus.SUCCESS,ResultConstants.INDEX_DELETE_SUCCESS);
	}

	public ResultEntity editProject(Project project,String typeId) {
		if (StringUtils.isNotBlank(typeId)) {
			ProjectType projectType = indexTypeRespository.findById(typeId).orElse(null);
			if (projectType == null) {
				return new ResultEntity(ResultStatus.ERROR,ResultConstants.INDEX_TYPE_ERROR);
			}else {
				project.setProjectType(projectType);
				//判断id是否存在 存在编辑 不存在新建
				if (StringUtils.isNotBlank(project.getProjectId())) {
					Project oldProject = iIndexRespository.findById(project.getProjectId()).orElse(null);
					//判断数据库中是否存在该对象 如果存在
					if (oldProject != null && oldProject.getProjectId() != null) {
						ProjectType oldProjectType = oldProject.getProjectType();
						MyBeanUtils.copyNonNullProperties(project.getProjectType(), oldProjectType);
						project.setProjectType(oldProjectType);
						MyBeanUtils.copyNonNullProperties(project, oldProject);
						project = oldProject;
					} else {
						return new ResultEntity(ResultStatus.ERROR,ResultConstants.NO_SUCH_OBJECT);
					}
				} else {
					//新增对象 是指标下的设备站点 关联指标
				}
				//验证指标
				ResultEntity resultEntity = validateProject(project);
				try {
					if (resultEntity.getCode() == 1) {
						return resultEntity;
					} else {
						iIndexRespository.saveAndFlush(project);
						return new ResultEntity(ResultStatus.SUCCESS,Constants.DEAL_SUCCESS);
					}
				} catch (Exception e) {
				//	e.printStackTrace();
					return new ResultEntity(ResultStatus.ERROR,Constants.DEAL_FAILUE);
				}
			}
		}else {
			return new ResultEntity(ResultStatus.ERROR,ResultConstants.INDEX_TYPE_ERROR);
		}
	}

	@Override
	public ResultEntity validateProject(Project project) {
		//验证指标和指标属性
		String message = IndexValidate.INDEX_SUCCESS.getReString();
		if (project.getProjectName().length() > 20) {
			message = IndexValidate.PROJECT_NAME.getReString();
		}else if (project.getProjectCode().length() > 20) {
			message = IndexValidate.PROJECT_CODE.getReString();
		}else if (project.getProjectUnit().length() > 10 ) {
			message = IndexValidate.PROJECT_UNIT.getReString();
		}
//		else if (project.getProjectType().getProjectTypeName().length() > 50) {
//			message = IndexValidate.PROJECT_TYPE_NAME.getReString();
//		}
//		else if (project.getProjectType().getRemark().length() > 50) {
//			message = IndexValidate.PROJECT_TYPE_REMARK.getReString();
//		}
		if (!message.equals(IndexValidate.INDEX_SUCCESS.getReString())) {
			return new ResultEntity(ResultStatus.ERROR,message);
		} else {
			return new ResultEntity(ResultStatus.SUCCESS,message);
		}
	}

	@Override
	public ResultEntity projectInfo() {
		List<Project> projects = iIndexRespository.findAll();
		List<ProjectInfoDto> list = new ArrayList<ProjectInfoDto>();
		for (Project project : projects) {
			ProjectInfoDto dto = new ProjectInfoDto();
			dto.setProjectId(project.getProjectId());
			dto.setProjectCode(project.getProjectCode());
			dto.setProjectName(project.getProjectName());
			list.add(dto);
		}
		return new ResultEntity(ResultStatus.SUCCESS,Constants.QUERY_SUCCESS).setDataList(list);
	}

	public ResultEntity getDownLine(HttpServletRequest request) {
		List<Project> projects = new ArrayList<Project>();
		try {
			List<String> stationIds = iFilterService.getStationIdByCookie(request);
			projects = iIndexRespository.queryBySatationId(stationIds);
		} catch (Exception e) {
			e.printStackTrace();
		}
		List<ProjectInfoDto> list = new ArrayList<ProjectInfoDto>();
		for (Project project : projects) {
			ProjectInfoDto dto = new ProjectInfoDto();
			dto.setProjectId(project.getProjectId());
			dto.setProjectCode(project.getProjectCode());
			dto.setProjectName(project.getProjectName());
			list.add(dto);
		}
		return new ResultEntity(ResultStatus.SUCCESS,Constants.QUERY_SUCCESS).setDataList(list);
	}

	public ResultEntity projectTree() {
		List<ProjectTreeVo> bodyList = new ArrayList<ProjectTreeVo>();// 保存除根结点（也可包含）其他节点
		List<ProjectTreeVo> rootList = new ArrayList<ProjectTreeVo>();// 保存根节点
		List<ProjectType> projectTypes = iIndexTypeRespository.findAll();
		List<Project> projects = iIndexRespository.findAll();
		for (ProjectType projectType : projectTypes) {
			if (StringUtils.isBlank(projectType.getParentId())) {
				ProjectTreeVo projectTreeVo = new ProjectTreeVo();
				projectTreeVo.setNodeId(projectType.getProjectTypeId());
				projectTreeVo.setNodeName(projectType.getProjectTypeName());
				rootList.add(projectTreeVo);
			} else {
				ProjectTreeVo projectTreeVo = new ProjectTreeVo();
				projectTreeVo.setNodeId(projectType.getProjectTypeId());
				projectTreeVo.setNodeName(projectType.getProjectTypeName());
				projectTreeVo.setPid(projectType.getParentId());
				bodyList.add(projectTreeVo);
			}
		}
		for (Project project : projects) {
			if (project.getProjectType() != null) {
				ProjectTreeVo projectTreeVo = new ProjectTreeVo();
				ProjectType projectType = project.getProjectType();
				projectTreeVo.setNodeId(project.getProjectId());
				projectTreeVo.setNodeName(project.getProjectName());
				projectTreeVo.setPid(projectType.getProjectTypeId());
				projectTreeVo.setProjectCode(project.getProjectCode());
				projectTreeVo.setUnit(project.getProjectUnit());
				projectTreeVo.setProjectName(project.getProjectName());
				bodyList.add(projectTreeVo);
			}
		}
		// 生成树，rootList包含根结点的集合，bodyList除根节点以外的集合
		ProjectTreeUtil utils = new ProjectTreeUtil(rootList, bodyList);
		List<ProjectTreeVo> list = utils.getTree();
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
	}

	public ResultEntity projectByName(String name) {
		List<Project> list = iIndexRespository.findByProjectName(name);
		return new ResultEntity(ResultStatus.SUCCESS,Constants.QUERY_SUCCESS).setDataList(list);
	}

}
